home *** CD-ROM | disk | FTP | other *** search
-
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <graphics/gfxbase.h>
- #include <intuition/intuitionbase.h>
- #include <libraries/iffparse.h>
- #include <utility/tagitem.h>
-
- #define __USE_SYSBASE 42
-
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <proto/utility.h>
-
- #include <string.h>
-
- #include "btd.h"
-
- struct GfxBase *GfxBase;
- struct IntuitionBase *IntuitionBase;
- struct Library *UtilityBase;
-
- #define TPTAG(o) (BTD_Client+(o))
-
- #define TP_Toasters TPTAG(0)
-
- #define MAX_TOASTERS 20L
- #define DEF_TOASTERS 2L
-
- #define NUM_IMAGES 4
-
- #define IMAGE_WIDTH 64
- #define IMAGE_HEIGHT 64
- #define IMAGE_WIDBUF (IMAGE_WIDTH+20)
- #define IMAGE_HEIBUF (IMAGE_HEIGHT+20)
-
- extern UBYTE *BytePackedFrames[];
-
- #define ABS(x) __builtin_abs(x)
- #define MIN(a,b) __builtin_min(a,b)
- #define MAX(a,b) __builtin_max(a,b)
-
- #define NUM_COLORS 16
- #define NUM_PHASES ((NUM_IMAGES*2)-2)
-
- struct BTDInteger ToasterIntParams[] =
- {
- TP_Toasters,"Toasters",BTDPT_INTEGER,DEF_TOASTERS,1L,MAX_TOASTERS,TRUE,
- };
-
- struct BTDNode *ToasterParams[] =
- {
- &ToasterIntParams[0].BI_Node,
- NULL
- };
-
- struct BTDInfo ToasterInfo =
- {
- BTDI_Revision,MAKE_ID('T','O','S','T'),
- "Toaster","The Must of Blankers","Markus Illenseer and Matthias Scheler",
- ToasterParams
- };
-
- struct IToaster
- {
- LONG delay;
- LONG x, y;
- LONG old_x, old_y;
- LONG xspeed, yspeed;
- LONG phase;
- LONG xcol, ycol;
- };
-
- struct Toasters /* structure for a swarm, including the wasp */
- {
- struct BTDDrawInfo *BTDDrawInfo;
- WORD Width; /* Width and */
- WORD Height; /* Height of the used area */
- WORD NumToaster; /* total number of the Toasters*/
- struct IToaster *Toasters;
- struct PlanarImage *Images[NUM_PHASES];
- LONG RandN,RandF,RandI;
- };
-
- UBYTE CMap[(NUM_COLORS-1)*3] =
- {
- 0x33,0x33,0x33,0x55,0x55,0x55,0x88,0x55,0x22,0x66,0x66,0x66,0x77,0x77,0x44,
- 0x55,0x55,0x66,0xEE,0x55,0x22,0x88,0x88,0x88,0x99,0x99,0x99,0xBB,0xBB,0xBB,
- 0xCC,0xCC,0xCC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE,0xEE,0xEE,0xFF,0xFF,0xFF
- };
-
- struct PlanarImage
- {
- WORD pi_Width,pi_Height;
- struct BitMap pi_BitMap;
- };
-
- /* library stuff */
-
- char MyBlankerName[] = "toaster.btd";
- char MyBlankerID[] = "Toaster Blanker V" VERSION "." REVISION " for BTD";
-
- LONG MyBlankerLibInit(void)
-
- {
- if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
- {
- if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
- {
- if (UtilityBase=OpenLibrary("utility.library",37L)) return TRUE;
-
- CloseLibrary (&IntuitionBase->LibNode);
- }
- CloseLibrary (&GfxBase->LibNode);
- }
- return FALSE;
- }
-
- void MyBlankerLibFree(void)
-
- {
- CloseLibrary (UtilityBase);
- CloseLibrary (&IntuitionBase->LibNode);
- CloseLibrary (&GfxBase->LibNode);
- }
-
- /* random generator */
-
- void __regargs InitRandom(struct Toasters *TP,ULONG Instance)
-
- {
- ULONG Time[2];
-
- CurrentTime (&Time[0],&Time[1]);
- TP->RandN=(LONG)Time[0];
-
- if (Time[1]<1024L) Time[1]|=1;
- else Time[1]>>=10;
- Time[1]^=Instance;
-
- TP->RandF=4*Time[1]+1;
- TP->RandI=2*Time[1]+1;
- }
-
- WORD __regargs Random(struct Toasters *TP,WORD Max)
-
- {
- TP->RandN=TP->RandF*TP->RandN+TP->RandI;
- if (TP->RandN<0L) TP->RandN=-TP->RandN;
-
- return (WORD)(TP->RandN%Max);
- }
-
- /* implementation of library functions */
-
- struct BTDInfo *QueryMyBlanker(void)
-
- {
- return &ToasterInfo;
- }
-
- void __regargs DeletePlanarImage(struct PlanarImage *PI)
-
- {
- ULONG Index,Size;
-
- Size=PI->pi_BitMap.BytesPerRow*PI->pi_BitMap.Rows;
- for (Index=0L; Index<PI->pi_BitMap.Depth; Index++)
- FreeMem (PI->pi_BitMap.Planes[Index],Size);
-
- FreeVec (PI);
- }
-
- struct PlanarImage __regargs *ConvertBytePacked(UBYTE *From,UWORD *RemapTab,
- struct RastPort *RastPort)
-
- {
- struct PlanarImage *Target;
- ULONG Index,Size;
- LONG Depth,X,Y;
-
- if ((Target=AllocVec(sizeof(struct PlanarImage),MEMF_PUBLIC))==NULL) return NULL;
-
- Target->pi_Width=IMAGE_WIDTH;
- Target->pi_Height=IMAGE_HEIGHT;
-
- Depth=1L;
- for (Index=1L; Index<NUM_COLORS; Index++)
- while (RemapTab[Index]>=(1L<<Depth)) Depth++;
-
- InitBitMap (&Target->pi_BitMap,Depth,Target->pi_Width,Target->pi_Height);
-
- Size=Target->pi_BitMap.BytesPerRow*Target->pi_BitMap.Rows;
- for (Index=0L; Index<Target->pi_BitMap.Depth; Index++)
- if ((Target->pi_BitMap.Planes[Index]=AllocMem(Size,MEMF_CHIP|MEMF_CLEAR))==NULL)
- {
- while (Index--) FreeMem (Target->pi_BitMap.Planes[Index],Size);
- FreeVec (Target);
- return NULL;
- }
-
- RastPort->BitMap=&Target->pi_BitMap;
-
- if (GfxBase->LibNode.lib_Version>=40)
- {
- ULONG Pixels;
- UBYTE *Data;
-
- Pixels=Target->pi_Width*Target->pi_Height;
- if (Data=AllocVec(Pixels,MEMF_PUBLIC))
- {
- UBYTE *To,Nibble;
-
- To=Data;
- while (Pixels)
- {
- Nibble=*From>>4;
- if (Nibble) *To++=RemapTab[Nibble];
- else *To++=BTD_BgPen;
-
- Nibble=(*From++)&15;
- if (Nibble) *To++=RemapTab[Nibble];
- else *To++=BTD_BgPen;
-
- Pixels-=2L;
- }
- WriteChunkyPixels (RastPort,0,0,Target->pi_Width-1,Target->pi_Height-1,Data,IMAGE_WIDTH);
-
- FreeVec (Data);
- return Target;
- }
- }
-
- for (Y=0L; Y<Target->pi_Height; Y++)
- for (X=0L; X<Target->pi_Width; X+=2)
- {
- UBYTE Nibble;
-
- Nibble=*From>>4;
- if (Nibble)
- { SetAPen (RastPort,RemapTab[Nibble]);
- (void)WritePixel(RastPort,X,Y);
- }
-
- Nibble=(*From++)&15;
- if (Nibble)
- { SetAPen (RastPort,RemapTab[Nibble]);
- (void)WritePixel(RastPort,X+1,Y);
- }
- }
-
- return Target;
- }
-
- void __regargs SafeEraseRect(struct BTDDrawInfo *BTDDrawInfo,
- LONG Left,LONG Top,
- LONG Right,LONG Bottom)
-
- {
- if ((Left<BTDDrawInfo->BDI_Width)&&(Right>=MAX(Left,0L))&&
- (Top<BTDDrawInfo->BDI_Height)&&(Bottom>=MAX(Top,0L)))
- EraseRect (BTDDrawInfo->BDI_RPort,
- BTDDrawInfo->BDI_Left+MAX(Left,0L),
- BTDDrawInfo->BDI_Top+MAX(Top,0L),
- BTDDrawInfo->BDI_Left+MIN(Right,BTDDrawInfo->BDI_Width-1),
- BTDDrawInfo->BDI_Top+MIN(Bottom,BTDDrawInfo->BDI_Height-1));
- }
-
- void __regargs DrawPlanarImage(struct BTDDrawInfo *BTDDrawInfo,
- struct PlanarImage *PI,
- LONG XPos,LONG YPos)
-
- {
- LONG Left,Top,Right,Bottom;
-
- Left=MAX(XPos,0L);
- Top=MAX(YPos,0L);
- Right=MIN(XPos+PI->pi_Width,BTDDrawInfo->BDI_Width);
- Bottom=MIN(YPos+PI->pi_Height,BTDDrawInfo->BDI_Height);
-
- if ((Left<Right)&&(Top<Bottom))
- BltBitMapRastPort (&PI->pi_BitMap,Left-XPos,Top-YPos,
- BTDDrawInfo->BDI_RPort,Left,Top,
- Right-Left,Bottom-Top,0xC0);
- }
-
- LONG __regargs TestExtent(struct Toasters *TP,LONG Start,LONG Me,LONG x,LONG y)
-
- {
- LONG Index;
-
- for (Index=Start; Index<TP->NumToaster; Index++)
- if ((Index!=Me)&&!TP->Toasters[Index].delay&&
- (ABS(x-TP->Toasters[Index].x)<IMAGE_WIDBUF)&&
- (ABS(y-TP->Toasters[Index].y)<IMAGE_HEIBUF)) return Index;
-
- return -1L;
- }
-
- BOOL __regargs FindLaunchPos(struct Toasters *TP,LONG Index)
-
- {
- LONG x,y;
-
- x=TP->Width-IMAGE_WIDTH;
- y=IMAGE_HEIGHT+Random(TP,TP->Height);
-
- FOREVER
- {
- if (x<=(2*IMAGE_WIDTH)) return FALSE;
-
- if (TestExtent(TP,0,Index,x,y)==-1L)
- {
- TP->Toasters[Index].x=TP->Toasters[Index].old_x=x;
- TP->Toasters[Index].y=TP->Toasters[Index].old_y=y;
- TP->Toasters[Index].xspeed=Random(TP,3)+1;
- TP->Toasters[Index].yspeed=Random(TP,2)+1;
- TP->Toasters[Index].phase=Random(TP,NUM_IMAGES);
-
- return TRUE;
- }
-
- if (y>(-IMAGE_HEIGHT)) y-=IMAGE_HEIGHT;
- else x-=IMAGE_WIDTH;
- }
- }
-
- LONG __regargs ActXSpeed(struct Toasters *TP,LONG Index)
-
- {
- if (TP->Toasters[Index].xcol==-1L) return TP->Toasters[Index].xspeed;
- else return ActXSpeed(TP,TP->Toasters[Index].xcol);
- }
-
- LONG __regargs ActYSpeed(struct Toasters *TP,LONG Index)
-
- {
- if (TP->Toasters[Index].ycol==-1L) return TP->Toasters[Index].yspeed;
- else return ActXSpeed(TP,TP->Toasters[Index].ycol);
- }
-
- struct Toasters *InitMyBlanker(struct TagItem *TagList)
-
- {
- struct BTDDrawInfo *BTDDrawInfo;
- ULONG *Error,Dummy,Instance,Index;
- LONG NumToaster;
- struct Toasters *TP;
- struct RastPort TempRastPort;
- UBYTE *CMapPtr;
-
- if ((BTDDrawInfo=(struct BTDDrawInfo *)
- GetTagData(BTD_DrawInfo,NULL,TagList))==NULL) return NULL;
- Error=(ULONG *)GetTagData(BTD_Error,(ULONG)&Dummy,TagList);
-
- Instance=GetTagData(BTD_Instance,0L,TagList);
- NumToaster=GetTagData(TP_Toasters,DEF_TOASTERS,TagList);
-
- if ((TP=AllocVec(sizeof(struct Toasters),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
- {
- *Error=BTDERR_Memory;
- return NULL;
- }
-
- if ((TP->Toasters=AllocVec(sizeof(struct IToaster)*NumToaster,MEMF_PUBLIC|MEMF_CLEAR))==NULL)
- {
- FreeVec (TP);
-
- *Error=BTDERR_Memory;
- return NULL;
- }
-
- InitRastPort (&TempRastPort);
- for (Index=0L; Index<NUM_IMAGES; Index++)
- if ((TP->Images[Index]=ConvertBytePacked(BytePackedFrames[Index],
- BTDDrawInfo->BDI_Pens-1,
- &TempRastPort))==NULL)
- {
- while (Index--) FreeVec (TP->Images[Index]);
- FreeVec (TP->Toasters);
- FreeVec (TP);
-
- *Error=BTDERR_Memory;
- return NULL;
- }
- for (; Index<NUM_PHASES; Index++)
- TP->Images[Index]=TP->Images[NUM_PHASES-Index];
-
- TP->BTDDrawInfo=BTDDrawInfo;
- TP->Width=BTDDrawInfo->BDI_Width;
- TP->Height=BTDDrawInfo->BDI_Height;
- TP->NumToaster=NumToaster;
-
- InitRandom (TP,Instance);
-
- for (Index=0L, CMapPtr=CMap; Index<(NUM_COLORS-1L); Index++)
- {
- BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=*CMapPtr++;
- BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=*CMapPtr++;
- BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=*CMapPtr++;
- BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
- }
-
- for (Index=0L; Index<NumToaster; Index++)
- if (!FindLaunchPos(TP,Index)) TP->Toasters[Index].delay=30;
-
- return TP;
- }
-
- void EndMyBlanker(struct Toasters *TP)
-
- {
- ULONG Index;
-
- for (Index=0L; Index<NUM_IMAGES; Index++) DeletePlanarImage (TP->Images[Index]);
- FreeVec (TP->Toasters);
- FreeVec (TP);
- }
-
- void AnimMyBlanker(struct Toasters *TP)
-
- {
- struct BTDDrawInfo *BTDDrawInfo;
- LONG i,j;
-
- BTDDrawInfo=TP->BTDDrawInfo;
-
- for (i=0; i<TP->NumToaster; i++)
- if (TP->Toasters[i].delay==0L)
- {
- TP->Toasters[i].old_x=TP->Toasters[i].x;
- TP->Toasters[i].old_y=TP->Toasters[i].y;
- TP->Toasters[i].x-=TP->Toasters[i].xspeed;
- TP->Toasters[i].y+=TP->Toasters[i].yspeed;
- TP->Toasters[i].xcol=-1;
- TP->Toasters[i].ycol=-1;
- }
-
- for (i=0; i<TP->NumToaster; i++)
- {
- if (TP->Toasters[i].delay==0L)
- {
- j=-1;
- while ((j=TestExtent(TP,j+1,i,TP->Toasters[i].x,TP->Toasters[i].y))>=0)
- {
- if (ABS(TP->Toasters[j].old_x-TP->Toasters[i].old_x)<(IMAGE_WIDBUF))
- {
- if (TP->Toasters[i].y<TP->Toasters[j].y) TP->Toasters[i].ycol=j;
- if (TP->Toasters[i].xspeed==TP->Toasters[j].xspeed) TP->Toasters[i].xspeed++;
- }
- else
- {
- if (TP->Toasters[i].x > TP->Toasters[j].x) TP->Toasters[i].xcol=j;
- if (TP->Toasters[i].yspeed==TP->Toasters[j].yspeed) TP->Toasters[i].yspeed++;
- }
- if (ABS(TP->Toasters[j].old_y-TP->Toasters[i].old_y)<(IMAGE_HEIBUF))
- {
- if (TP->Toasters[i].x > TP->Toasters[j].x) TP->Toasters[i].xcol=j;
- if (TP->Toasters[i].yspeed==TP->Toasters[j].yspeed) TP->Toasters[i].yspeed++;
- }
- }
- }
- }
-
- for (i=0; i<TP->NumToaster; i++)
- {
- if (TP->Toasters[i].delay==0L)
- {
- TP->Toasters[i].x=TP->Toasters[i].old_x-ActXSpeed(TP,i);
- TP->Toasters[i].y=TP->Toasters[i].old_y + ActYSpeed(TP,i);
- }
- }
-
- for (i=0; i<TP->NumToaster; i++)
- {
- if (TP->Toasters[i].delay==0L)
- {
- j=-1;
- while ((j=TestExtent(TP,j+1,i,TP->Toasters[i].x,TP->Toasters[i].y))>=0)
- {
- if (ABS(TP->Toasters[j].old_x-TP->Toasters[i].old_x)<(IMAGE_WIDBUF))
- if (TP->Toasters[i].x > TP->Toasters[j].x) TP->Toasters[i].x=TP->Toasters[i].old_x;
- else
- if (TP->Toasters[i].y<TP->Toasters[j].y) TP->Toasters[i].y=TP->Toasters[i].old_y;
-
- if (ABS(TP->Toasters[j].old_y-TP->Toasters[i].old_y)<(IMAGE_HEIBUF))
- if (TP->Toasters[i].y<TP->Toasters[j].y)
- TP->Toasters[i].y=TP->Toasters[i].old_y;
- }
- }
- }
-
- for (i=0; i<TP->NumToaster; i++)
- if (TP->Toasters[i].delay==0L)
- {
- TP->Toasters[i].phase=(TP->Toasters[i].phase+1)%NUM_PHASES;
-
- SafeEraseRect (BTDDrawInfo,
- TP->Toasters[i].x+IMAGE_WIDTH,
- TP->Toasters[i].old_y,
- TP->Toasters[i].x+IMAGE_WIDTH+TP->Toasters[i].xspeed,
- TP->Toasters[i].old_y+IMAGE_HEIGHT);
- SafeEraseRect (BTDDrawInfo,
- TP->Toasters[i].old_x,
- TP->Toasters[i].old_y,
- TP->Toasters[i].old_x+IMAGE_WIDTH,
- TP->Toasters[i].old_y+TP->Toasters[i].yspeed);
-
- DrawPlanarImage (BTDDrawInfo,TP->Images[TP->Toasters[i].phase],
- TP->Toasters[i].x,TP->Toasters[i].y);
-
- if ((TP->Toasters[i].x<=(-IMAGE_WIDTH-1))||
- (TP->Toasters[i].y>=TP->Height)) TP->Toasters[i].delay=Random(TP,50);
- }
- else
- if (--TP->Toasters[i].delay==0L)
- TP->Toasters[i].delay=FindLaunchPos(TP,i)?0:30;
-
- WaitTOF();
- }
-
- ULONG PenCountMyBlanker(struct TagItem *TagList)
-
- {
- return NUM_COLORS-1L;
- }
-